package com.powerband.testapiandroid

import android.annotation.SuppressLint
import android.app.DatePickerDialog
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.text.method.ScrollingMovementMethod
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ShareCompat
import androidx.recyclerview.widget.GridLayoutManager
import com.alibaba.fastjson.JSON
import com.powerband.apiheartrate.base.*
import com.powerband.apiheartrate.ble.fbkBleDevice.FBKBleDeviceStatus
import com.powerband.apiheartrate.heartrate.FBKApiHeartRate
import com.powerband.apiheartrate.heartrate.FBKBleCallBack
import com.powerband.apiheartrate.heartrate.FBKHearRateCallBack
import com.powerband.apiheartrate.ota.OtaError
import com.powerband.apiheartrate.ota.OtaStatus
import com.powerband.testapiandroid.command.CommandBtnAdapter
import com.powerband.testapiandroid.databinding.ActivityCommandDemoBinding
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.*
import kotlin.concurrent.timerTask

class CommandDemoActivity : AppCompatActivity() {
    private lateinit var binding: ActivityCommandDemoBinding
    lateinit var adapter: CommandBtnAdapter
    private var lightOn = false
    private  var isSport = false
    private var timerAlive: Timer? = null
    val simpleDateFormat: SimpleDateFormat = SimpleDateFormat("yyyy-MM-dd")
    val fullFmt:SimpleDateFormat =  SimpleDateFormat("yyyy-MM-dd HH:mm:ss")

    private val current =  listOf<String>("日常模式","运动模式")
    private val source =  listOf<String>("自动进入","app进入")
    private val sportLevel =  listOf<String>("日常","轻度运动", "重度运动")


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityCommandDemoBinding.inflate(layoutInflater)
        setContentView(binding.root)
        initSDK()
        initAdapter()

        val ca = Calendar.getInstance()
        var mYear = ca[Calendar.YEAR]
        var mMonth = ca[Calendar.MONTH]
        var mDay = ca[Calendar.DAY_OF_MONTH]
        val start = "${mYear}-${mMonth + 1}-${mDay - 1}"
        val end = "${mYear}-${mMonth + 1}-${mDay}"
        binding.textView2.text = start
        binding.textView3.text = end

        currentTime()
    }


    private fun initAdapter() {
        adapter = CommandBtnAdapter(
            arrayListOf(
                "获取电量",
                "Manufacture",
                "Model",
                "Hardware",
                "Firmware",
                "Software",
                "SysId",
                "同步时间",
                "序列号",
                "实时步频",
                "实时血氧",
                "充电状态",
                "心率汇总",
                "步数汇总",
                "血氧汇总",
                "压力汇总",
                "卡路里汇总",
                "睡眠汇总",
                "运动汇总",
                "日常明细",
                "运动明细",
                "日常模式",
                "运动模式",
                "模式查询",
                "导出日志",
                "当前时间",
                "查询运动状态",
                "恢复出厂设置",
                "退出睡眠算法",
                "切换灯光"
            )
        ) { index, name ->
            handleEvent(index, name)
        }
        binding.btnListView.layoutManager = GridLayoutManager(this, 3)
        binding.btnListView.adapter = adapter
        binding.logView.movementMethod = ScrollingMovementMethod.getInstance()
        binding.sendThreshold.setOnClickListener {
            setThreshold()
        }

        binding.textView2.setOnClickListener {
            buttonFunc(it)
        }

        binding.textView3.setOnClickListener {
            buttonFunc(it)
        }
        binding.sendThreshold2.setOnClickListener {
            syncToBand()
        }

        binding.button6.setOnClickListener {
            resultCallback.launch(1)
        }
    }


    private val resultCallback = registerForActivityResult(GetTimeFromAc()) {
        result ->
        if (result.size > 4) {
            val en = result[0] == 1
            logInfo("设置免打扰时间：${result}")
            FBKApiHeartRate.setDoNotDisturbTime(en,result[1],result[2],result[3],result[4])
        }
    }



    private fun handleEvent(index: Int, str: String) {
        logInfo("开始 $str:")
        when (index) {
            0 -> FBKApiHeartRate.readDeviceBatteryPower()
            1 -> FBKApiHeartRate.readManufacturerName()
            2 -> FBKApiHeartRate.readModelString()
            3 -> FBKApiHeartRate.readHardwareVersion()
            4 -> FBKApiHeartRate.readFirmwareVersion()
            5 -> FBKApiHeartRate.readSoftwareVersion()
            6 -> FBKApiHeartRate.readSystemId()
            7 -> FBKApiHeartRate.syncTime()
            8 -> FBKApiHeartRate.getDeviceSerial()
            9 -> FBKApiHeartRate.getDeviceStepFrequency()
            10 -> FBKApiHeartRate.getRealTimeOxygen()
            11 -> FBKApiHeartRate.queryBatteryStatus()
            12 -> {
                val value = getTimes()
                val d1 = value[0]
                val d2 = value[1]
                FBKApiHeartRate.getSummaryHeartRate(d1.toLong(), d2.toLong())
            }
            13 -> {
                val value = getTimes()
                val d1 = value[0]
                val d2 = value[1]
                FBKApiHeartRate.getSummarySteps(d1.toLong(), d2.toLong())
            }
            14 -> {
                val value = getTimes()
                val d1 = value[0]
                val d2 = value[1]
                FBKApiHeartRate.getSummaryBloodOxygen(d1.toLong(), d2.toLong())
            }
            15 -> {
                val value = getTimes()
                val d1 = value[0]
                val d2 = value[1]
                FBKApiHeartRate.getSummaryPressureIndex(d1.toLong(), d2.toLong())
            }
            16 -> {
                val value = getTimes()
                val d1 = value[0]
                val d2 = value[1]
                FBKApiHeartRate.getSummaryCalorie(d1.toLong(), d2.toLong())
            }
            17 -> {
                val value = getTimes()
                val d1 = value[0]
                val d2 = value[1]
                FBKApiHeartRate.getSummarySleep(d1.toLong(), d2.toLong())
            }
            18 -> {
                val value = getTimes()
                val d1 = value[0]
                val d2 = value[1]
                FBKApiHeartRate.getExerciseData(d1.toLong(), d2.toLong())
            }
            19 -> {
                isSport = false
                var sm = binding.thresholdTxtViewLeft2.text.toString().toIntOrNull() ?: 100
                FBKApiHeartRate.getMotionData(sm, false)
            }
            20 -> {
                isSport = true
                var sm = binding.thresholdTxtViewLeft2.text.toString().toIntOrNull() ?: 60
                FBKApiHeartRate.getMotionData(sm, true)
            }
            21 -> FBKApiHeartRate.switchDevieMode(FBKDeviceMode.Daily)
            22 -> FBKApiHeartRate.switchDevieMode(FBKDeviceMode.Sport)
            23 -> FBKApiHeartRate.queryDeviceMode()
            24 -> exportLogs()
            25 -> currentTime()
            26 -> FBKApiHeartRate.qureySportModeDetail()
            27 -> FBKApiHeartRate.resetFactory()
            28 -> FBKApiHeartRate.forseSleepOut()
            29 -> {
                FBKApiHeartRate.lightSwitch(lightOn)
                lightOn = !lightOn
            }
            else -> {
                Toast.makeText(this, "功能开发中", Toast.LENGTH_LONG).show()
            }
        }
    }

    fun currentTime() {
        FBKApiHeartRate.requestCurrentTime()
    }
    fun  exportLogs() {
        val ca = Calendar.getInstance()
        var mYear = ca[Calendar.YEAR]
        var mMonth = ca[Calendar.MONTH]
        var mDay = ca[Calendar.DAY_OF_MONTH]
        val hh = ca[Calendar.HOUR_OF_DAY]
        val mm = ca[Calendar.MINUTE]
        val end = "${mYear}-${mMonth + 1}-${mDay} $hh $mm"
        val r = storeExcelInStorage(this, "${end}-Log.txt", binding.logView.text.toString())
        if (r) {
            launchShareFileIntent(FileShareUtils.accessFile(this, "${end}-Log.txt"))
        }
    }
    fun getTimes(): List<Double> {
        val d1 = (simpleDateFormat.parse(binding.textView2.text.toString())?.time ?: 0) / 1000.0
        val d2 = (simpleDateFormat.parse(binding.textView3.text.toString())?.time ?: 0) / 1000.0
//        val d1 = simpleDateFormat.parse("2023-06-30 09:10:22").time / 1000.0
//        val d2 = simpleDateFormat.parse("2023-06-30 18:10:22").time / 1000.0
        return listOf(d1, d2)
    }

    private fun syncToBand() {
        FBKApiHeartRate.updateSeq(isSport)
    }

    private fun setThreshold() {
        val valueStr = binding.thresholdTxtViewLeft.text.toString()
        val valueStr2 = binding.thresholdTxtViewRight.text.toString()
        if (valueStr.isNotEmpty() && valueStr2.isNotEmpty()) {
            val valueInt = valueStr.toInt()
            val valueInt2 = valueStr2.toInt()
            logInfo("设置心跳阈值 $valueStr:")
            FBKApiHeartRate.setDeviceThreshold(valueInt, valueInt2)
        } else {
            logInfo("设置心跳阈值 输入不正确")
        }
    }
    private fun logTime(): String {
        return SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())
    }
    @SuppressLint("SetTextI18n")
    private fun logInfo(str: String) {
        runOnUiThread {
            val timeStr = logTime()
            binding.logView.apply {
                append("$timeStr $str \n")
                val offset = lineCount * lineHeight
                if (offset > height) {
                    scrollTo(0, offset - height - 20)
                }
            }
        }
    }

    private fun initSDK() {
        FBKApiHeartRate.setBasicInfoCallBack(object : FBKBasicInfoCallBack {
            override fun batteryPower(value: Int, baseMethod: FBKApiBaseMethod?) {
                logInfo("电量为：$value")
            }

            override fun protocolVersion(version: String?, baseMethod: FBKApiBaseMethod?) {

            }

            override fun firmwareVersion(version: String?, baseMethod: FBKApiBaseMethod?) {
                logInfo("固件为：$version")
            }

            override fun hardwareVersion(version: String?, baseMethod: FBKApiBaseMethod?) {
                logInfo("硬件为：$version")
            }

            override fun softwareVersion(version: String?, baseMethod: FBKApiBaseMethod?) {
                logInfo("软件为：$version")
            }

            override fun armBandPlayStatusChange() {
                logInfo("切换播放状态")
            }

            override fun armBandUnbind() {
                logInfo("收到解绑指令")
                FBKApiHeartRate.disconnectBle()
            }

            override fun batteryStatus(state: BatteryStatus) {
                logInfo("充电状态为$state")
            }

            override fun privateVersion(
                paramMap: Map<String?, String?>?,
                baseMethod: FBKApiBaseMethod?
            ) {
            }

            override fun privateMacAddress(
                paramMap: Map<String?, String?>?,
                baseMethod: FBKApiBaseMethod?
            ) {

            }

            override fun bleConnectInfo(info: String?, baseMethod: FBKApiBaseMethod?) {

            }

            override fun deviceSystemID(data: ByteArray?, baseMethod: FBKApiBaseMethod?) {
                logInfo("systemID：${data}")
            }

            override fun deviceModelString(model: String?, baseMethod: FBKApiBaseMethod?) {
                logInfo("Model：$model")
            }

            override fun deviceSerialNumber(value: String?, baseMethod: FBKApiBaseMethod?) {
                logInfo("序列号：$value")
            }

            override fun deviceManufacturerName(name: String?, baseMethod: FBKApiBaseMethod?) {
                logInfo("manufacture：$name")
            }

            override fun deviceBaseInfo(baseInfo: FBKBleBaseInfo?, baseMethod: FBKApiBaseMethod?) {

            }

            override fun deviceTimeSynced() {
                logInfo("时间已同步")
            }

            override fun deviceThresholdChanged() {
                logInfo("阈值已更新")
            }

            override fun deviceOxygen(value: Int?, baseMethod: FBKApiBaseMethod?) {
                logInfo("血氧：$value")
            }

            override fun deviceStepFrequency(value: Int?, baseMethod: FBKApiBaseMethod?) {
                logInfo("步频：$value")
            }

            override fun devicePressure(value: Int?, baseMethod: FBKApiBaseMethod?) {
                logInfo("压力值：$value")
            }

            override fun exitedSleepAlgorithm() {
                logInfo("强制退出心率算法")
            }

            override fun armBandModeChanged(mode: FBKDeviceMode, type: FBKModeType) {
                val md = when (type) {
                    FBKModeType.AutoIn -> "自动进入"
                    FBKModeType.AutoOut -> "自动退出"
                    FBKModeType.Other -> "其他"
                }
                logInfo("当前模式：${if (mode == FBKDeviceMode.Daily) "日常" else "运动"} 模式，类型：$md")
                fireMyTime(mode == FBKDeviceMode.Daily)
            }

            override fun heartRateInMeasuring() {
                logInfo("心率测量中")
            }

            override fun summaryHeartRateInfo(info: List<Map<String, Any>>) {
                formatPrint(info)
            }

            override fun summaryStepsInfo(info: List<Map<String, Any>>) {
                formatPrint(info)
            }

            override fun summaryBloodOxygenInfo(info: List<Map<String, Any>>) {
                formatPrint(info)
            }

            override fun summaryPressureIndexInfo(info: List<Map<String, Any>>) {
                formatPrint(info)
            }

            override fun summarySleepInfo(info: List<Map<String, Any>>) {
                formatPrint(info)
            }

            override fun summaryCalorieInfo(info: List<Map<String, Any>>) {
                formatPrint(info)
            }

            override fun summaryExerciseInfo(info: List<Map<String, Any>>) {
                formatPrint(info)
            }

            override fun motionDataInfo(info: List<Map<String, Any>>, isSport: Boolean) {
                formatPrint(info)
            }

            override fun logOutBufferData(data: List<Byte>) {
                logInfo(bytesToHex(data.toByteArray()))
            }

            override fun motionDataSeqUpdated(isSport: Boolean) {
                logInfo("${if(isSport) "运动历史" else "日常历史" }游标数据已更新")
            }

            override fun currentBandTime(timeNow: Long) {
                logInfo("当前手环时间：${fullFmt.format(timeNow)}")
            }

            override fun sportModeDetailInfo(info: Map<String, Int>) {
                val infos = mapOf<String, Any>(
                    "当前模式" to current[info["current"] ?:0],
                    "模式来源" to source[info["type"] ?:0],
                    "运动等级" to sportLevel[info["level"] ?:0],
                    "日常累计" to (info["daily"]?:0),
                    "轻度累计" to (info["low"]?:0) ,
                    "重度累计" to (info["heavy"] ?:0),
                    "当前心率" to (info["rate"] ?:0),
                    "运动区间1" to (info["sp1"] ?:0),
                    "运动区间2" to (info["sp2"] ?:0),
                    "运动区间3" to (info["sp3"] ?:0),
                    "日常区间1" to (info["dl1"] ?:0),
                    "日常区间2" to (info["dl2"] ?:0),
                    "日常区间2" to (info["dl3"] ?:0)
                )
                formatPrint(listOf(infos))
            }

            override fun heartRateLog(logList: List<Any>) {
                logInfo("心率日志：${logList}")
            }

            override fun lightStatusChanged(on: Boolean) {
                logInfo("灯光状态：${if (on) '开' else '关'}")
            }

            override fun totalPacket(num: Int) {
                logInfo("总数据包数：${num}")
            }

            override fun doNotDisturbTimeInfo(
                enabled: Boolean
            ) {
                logInfo("免打扰时间已设置！")
            }
        }).setHeartRateCallBack(javaClass.name, object : FBKHearRateCallBack {
            override fun deviceHeartRate(rate: Int, baseMethod: FBKApiBaseMethod?) {
                Log.d("DEMO", "收到心率值$rate")
                logInfo("收到心率值$rate")
            }
        }).setBleCallBack(javaClass.name,object : FBKBleCallBack {
            override fun bleConnectError(errorStr: String?, baseMethod: FBKApiBaseMethod?) {
                //logInfo("bleConnectError--$this, ---$errorStr")
            }

            override fun bleConnectStatus(
                deviceStatus: FBKBleDeviceStatus?,
                baseMethod: FBKApiBaseMethod?
            ) {
               if (deviceStatus == FBKBleDeviceStatus.BleDisconnected) {
                   finish()
               }
                //logInfo("bleConnectStatus--$this, ---$deviceStatus")
            }

            override fun bleConnectStatusLog(logStr: String?, baseMethod: FBKApiBaseMethod?) {
            }

            override fun bleOtaLog(state: OtaStatus, progress: Float) {}

            override fun bleOtaError(error: OtaError) {}

        } )
    }

    fun fireMyTime(stop: Boolean) {
        if (timerAlive == null) {
            timerAlive = Timer()
        }
       if (stop) {
           timerAlive?.cancel()
       } else {
           val myAckTask = timerTask {
               kotlin.run {
                   logInfo("发送运功m模式心跳========")
                   FBKApiHeartRate.keepSportAlive()
               }
           }
           timerAlive?.schedule(myAckTask,0,10 * 1000)
       }

    }
    fun formatPrint(info: List<Map<String, Any>>) {
        logInfo("总条数: ${info.size}")
        logInfo(JSON.toJSONString(info,true))
    }



    fun buttonFunc(view: View) {
        when (view.id) {
            R.id.textView2 -> {
                // 日期选择器
                val ca = Calendar.getInstance()
                var mYear = ca[Calendar.YEAR]
                var mMonth = ca[Calendar.MONTH]
                var mDay = ca[Calendar.DAY_OF_MONTH]

                val datePickerDialog = DatePickerDialog(
                    this,
                    DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth ->
                        mYear = year
                        mMonth = month
                        mDay = dayOfMonth
                        val mDate = "${year}-${month + 1}-${dayOfMonth}"
                        // 将选择的日期赋值给TextView
                        binding.textView2.text = mDate
                    },
                    mYear, mMonth, mDay
                )
                datePickerDialog.show()
            }
            R.id.textView3 -> {
                val ca = Calendar.getInstance()
                var mYear = ca[Calendar.YEAR]
                var mMonth = ca[Calendar.MONTH]
                var mDay = ca[Calendar.DAY_OF_MONTH]

                val datePickerDialog = DatePickerDialog(
                    this,
                    DatePickerDialog.OnDateSetListener { _, year, month, dayOfMonth ->
                        mYear = year
                        mMonth = month
                        mDay = dayOfMonth
                        val mDate = "${year}-${month + 1}-${dayOfMonth}"
                        // 将选择的日期赋值给TextView
                        binding.textView3.text = mDate
                    },
                    mYear, mMonth, mDay
                )
                datePickerDialog.show()
            }
        }
    }

//    R.id.textView3 -> {
//        // 时间选择器
//        val ca = Calendar.getInstance()
//        var mHour = ca[Calendar.HOUR_OF_DAY]
//        var mMinute = ca[Calendar.MINUTE]
//
//        val timePickerDialog = TimePickerDialog(
//            this,
//            TimePickerDialog.OnTimeSetListener{_, hourOfDay, minute ->
//                mHour   = hourOfDay
//                mMinute = minute
//                val mTime = "${hourOfDay}:${minute}"
//                time_textT.text = mTime
//            },
//            mHour, mMinute, true
//        )
//        timePickerDialog.show()
//    }

    private val strArry = listOf<String>("")
    private val hexArray = "0123456789ABCDEF".toCharArray()
    fun bytesToHex(bytes: ByteArray): String {
        val hexChars = CharArray(bytes.size * 2)
        bytes.forEachIndexed { j, byte ->
            val v = (bytes[j].toInt() and 0xFF)
            hexChars[j * 2] = hexArray[v ushr 4]
            hexChars[j * 2 + 1] = hexArray[v and 0x0F]
        }
        var stringBuffer = StringBuilder()
        stringBuffer.append("[ ")
        hexChars.forEachIndexed { index, c ->
            stringBuffer.append(c)
            if (index % 2 == 1) {
                stringBuffer.append(" ")
            }
        }
        stringBuffer.append(" ]")

        return stringBuffer.toString()
    }

    private fun storeExcelInStorage(
        context: Context,
        fileName: String,
        workbook: String
    ): Boolean {
        var isSuccess: Boolean
        val file = File(context.getExternalFilesDir(null), fileName)
        var fileOutputStream: FileOutputStream? = null
        try {
            fileOutputStream = FileOutputStream(file)
            fileOutputStream.write(workbook.toByteArray())
            isSuccess = true
        } catch (e: IOException) {
            isSuccess = false
        } catch (e: Exception) {
            isSuccess = false
        } finally {
            try {
                fileOutputStream?.close()
            } catch (ex: Exception) {
                ex.printStackTrace()
            }
        }
        return isSuccess
    }

    private fun launchShareFileIntent(uri: Uri) {
        val intent = ShareCompat.IntentBuilder.from(this)
            .setType("text/plain")
            .setStream(uri)
            .setChooserTitle("Select application to share file")
            .createChooserIntent()
            .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
        startActivity(intent)
    }

    override fun onDestroy() {
        FBKApiHeartRate.removeHeartRateCallBack(javaClass.name)
        FBKApiHeartRate.removeBleCallBack(javaClass.name)
        super.onDestroy()
    }
}